<script lang="ts" setup>
import type { TreeOverrideNodeClickBehavior } from 'naive-ui';
import { onMounted, ref, shallowRef, watch } from 'vue';
import type { User } from '@/service/api';
import { fetchAllDeptOptions, fetchGetUserList } from '@/service/api';
import { $t } from '@/locales';
import { useTable, useTableOperate } from '@/hooks/common/table';
import { useAppStore } from '@/store/modules/app';
import { DICT_TYPE, getDictObj } from '@/utils/dict';

defineOptions({
  name: 'EmployeePickModal'
});

const submitLoading = ref(false);

interface Emits {
  (e: 'fill'): void;
}

const emit = defineEmits<Emits>();

interface Props {
  /** 是否单选，1：单选；2：多选；默认单选 */
  singleSelection: number | 1;
  employeeList: User[] | [];
}

const props = defineProps<Props>();

const visible = defineModel<boolean>('visible', {
  default: false
});

const appStore = useAppStore();

const queryFormRef = ref(); // 搜索的表单
const deptTree = shallowRef<Api.Common.TreeOptions[]>([]);
const employeeSelectedList = ref<User[]>([]); // 最终选中传给父组件的人员

const { columns, data, getData, getDataByPage, loading, pagination, searchParams, resetSearchParams } = useTable({
  apiFn: fetchGetUserList,
  immediate: false,
  showTotal: true,
  apiParams: {
    current: 1,
    size: 15,
    nickname: null
  },
  columns: () => [
    {
      type: 'selection',
      multiple: props.singleSelection !== 1
    },
    {
      key: 'nickname',
      title: $t('page.manage.user.nickName'),
      align: 'center',
      width: 120,
      ellipsis: {
        tooltip: true
      }
    },
    {
      key: 'deptName',
      title: $t('page.manage.user.deptName'),
      align: 'center',
      width: 120,
      ellipsis: {
        tooltip: true
      }
    },
    {
      key: 'username',
      title: $t('page.manage.user.userName'),
      align: 'center',
      width: 120
    },
    {
      key: 'gender',
      title: $t('page.manage.user.userGender'),
      align: 'center',
      width: 100,
      render: row => {
        if (row.gender === null) {
          return null;
        }
        const dictObj = getDictObj(DICT_TYPE.SYSTEM_USER_SEX, row.gender);

        return dictObj?.label;
      }
    }
  ]
});

const { checkedRowKeys } = useTableOperate(data, getData);

function closeDrawer() {
  employeeSelectedList.value = [];
  checkedRowKeys.value = [];
  handleSubmit();
}

async function handleSubmit() {
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-expect-error
  emit('fill', employeeSelectedList.value);
  submitLoading.value = false;
  visible.value = false;
}

async function getDeptTree() {
  const res = await fetchAllDeptOptions();

  if (!res.error) {
    if (!res.data[0] || !res.data[0].children) {
      deptTree.value = []; // 或者其他适当的默认值
    } else {
      deptTree.value = res.data[0].children;
    }
  }
}

const handleDeptTreeNodeClick: TreeOverrideNodeClickBehavior = ({ option }) => {
  resetSearchParams();
  searchParams.deptId = option.value as number;
  // 查询用户
  getDataByPage();
  return 'none';
};

const handleAllDeptClick = async () => {
  resetSearchParams();
  searchParams.deptId = null;
  // 查询用户
  getDataByPage();
};

const handleUserSearch = () => {
  resetSearchParams();
  searchParams.deptId = null;
  getDataByPage();
};

const handleUserReset = () => {
  resetSearchParams();
  handleUserSearch();
};

function handleUpdateCheckedRowKeys(
  checkedValue: Array<string | number>,
  rows: object[],
  meta: { row: object | undefined; action: 'check' | 'uncheck' | 'checkAll' | 'uncheckAll' }
) {
  const curRow = meta.row as User;
  const curRows = rows as User[];
  if (meta.action === 'check') {
    employeeSelectedList.value.unshift(curRow);
  } else if (meta.action === 'checkAll') {
    curRows.filter(item => item !== undefined).map(item => employeeSelectedList.value.unshift(item));
  } else if (meta.action === 'uncheck') {
    employeeSelectedList.value = employeeSelectedList.value.filter(item => !(curRow.id === item.id));
  } else if (meta.action === 'uncheckAll') {
    employeeSelectedList.value = employeeSelectedList.value.filter(item => checkedValue.includes(item.id));
  }
}

const handleEmployeeSelectedDelete = async (tag: User) => {
  checkedRowKeys.value = checkedRowKeys.value.filter(item => !(tag.id.toString() === item.toString()));
  employeeSelectedList.value = employeeSelectedList.value.filter(item => !(tag.id === item.id));
};

watch(visible, () => {
  if (visible.value) {
    employeeSelectedList.value = [];
    checkedRowKeys.value = [];
    if (props.employeeList) {
      props.employeeList.forEach(item => {
        employeeSelectedList.value.unshift(item);
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-expect-error
        checkedRowKeys.value.unshift(item.id);
      });
    }
  }
});

onMounted(() => {
  getDeptTree();
  getDataByPage();
});
</script>

<template>
  <NModal v-model:show="visible">
    <NCard :title="$t('page.manage.user.userPickModal.title')" class="w-75%">
      <NGrid :x-gap="12" :y-gap="8" :cols="24">
        <!-- 左侧部门树 -->
        <NGridItem :span="5" class="border-1 border-gray-500/20 rounded-md">
          <div class="h-full overflow-hidden lt-sm:overflow-auto">
            <div class="h-2.75rem bg-cyan-700 text-align-center text-white font-bold leading-11">
              {{ $t('page.manage.user.userPickModal.dept') }}
            </div>
            <div
              class="div-all-employee mt-2 cursor-pointer pb-2 pl-2 pt-2 transition-transform"
              @click="handleAllDeptClick"
            >
              <span class="transition">
                {{ $t('page.manage.user.userPickModal.allEmployee') }}
              </span>
            </div>
            <NTree
              :data="deptTree"
              :show-irrelevant-nodes="false"
              key-field="value"
              :expand-on-click="false"
              virtual-scroll
              block-line
              :default-expand-all="true"
              class="h-150"
              :override-default-node-click-behavior="handleDeptTreeNodeClick"
            />
          </div>
        </NGridItem>
        <!-- 搜索 -->
        <NGridItem :span="14">
          <div class="h-full overflow-hidden lt-sm:overflow-auto">
            <NForm ref="queryFormRef" :model="searchParams" label-placement="left" label-width="auto">
              <NGrid responsive="screen" item-responsive>
                <NFormItemGi span="24 s:16 m:10" :label="$t('page.manage.user.userName')" path="nickname" class="ml-20">
                  <NInput
                    v-model:value="searchParams.nickname"
                    clearable
                    :placeholder="$t('page.manage.user.form.userName')"
                  />
                </NFormItemGi>
                <NFormItemGi span="24 s:12 m:8">
                  <NSpace class="w-full" justify="end">
                    <NButton @click="handleUserReset">
                      <template #icon>
                        <icon-ic-round-refresh class="text-icon" />
                      </template>
                      {{ $t('common.reset') }}
                    </NButton>
                    <NButton type="primary" ghost @click="handleUserSearch">
                      <template #icon>
                        <icon-ic-round-search class="text-icon" />
                      </template>
                      {{ $t('common.search') }}
                    </NButton>
                  </NSpace>
                </NFormItemGi>
              </NGrid>
            </NForm>
            <NCard size="small" class="mt-10 sm:flex-1-hidden card-wrapper">
              <NDataTable
                v-model:checked-row-keys="checkedRowKeys"
                :columns="columns"
                :data="data"
                size="small"
                :flex-height="!appStore.isMobile"
                :scroll-x="962"
                :loading="loading"
                remote
                :row-key="row => row.id"
                :pagination="pagination"
                class="sm:h-150"
                :on-update-checked-row-keys="handleUpdateCheckedRowKeys"
              ></NDataTable>
            </NCard>
          </div>
        </NGridItem>
        <!-- 右侧选中列表 -->
        <NGridItem :span="5" class="border-1 border-gray-500/20 rounded-md">
          <div class="h-full overflow-hidden lt-sm:overflow-auto">
            <div class="h-2.75rem bg-cyan-700 pl-5 text-white font-bold leading-11">
              <span>{{ $t('page.manage.user.userPickModal.selectedEmployee') }}</span>
              <div class="float-right h-2.5rem pr-2 leading-10">
                <NButton size="tiny" color="white" text-color="black" :focusable="false" :round="false">
                  <template #icon>
                    <NIcon>
                      <icon-ep:delete />
                    </NIcon>
                  </template>
                  {{ $t('page.manage.user.userPickModal.deleteAll') }}
                </NButton>
              </div>
            </div>
            <div class="div-all-employee mt-2 h-180 overflow-y-scroll">
              <div class="div-no-data cursor-pointer pb-2 pl-2 pt-2 transition-transform">
                <div v-if="employeeSelectedList.length == 0" class="text-align-center transition">
                  {{ $t('common.noData') }}
                </div>
              </div>
              <div v-if="employeeSelectedList.length != 0">
                <NTag
                  v-for="tag in employeeSelectedList"
                  :key="tag.id"
                  class="mb-1 h-12 w-full pl-20%"
                  size="large"
                  closable
                  type="primary"
                  @close="handleEmployeeSelectedDelete(tag)"
                >
                  <span class="truncate text-center">{{ tag.deptName }}</span>
                  <span class="ml-5 truncate text-center">{{ tag.nickname }}</span>
                  <DictTag
                    class="ml-5 truncate text-center"
                    :type="DICT_TYPE.SYSTEM_USER_SEX"
                    :value="tag.gender as string"
                  />
                </NTag>
              </div>
            </div>
          </div>
        </NGridItem>
      </NGrid>
      <template #footer>
        <NSpace justify="end" :size="16">
          <NButton @click="closeDrawer">{{ $t('common.cancel') }}</NButton>
          <NButton type="primary" :loading="submitLoading" @click="handleSubmit">{{ $t('common.confirm') }}</NButton>
        </NSpace>
      </template>
    </NCard>
  </NModal>
</template>

<style scoped>
.div-no-data:hover {
  --tw-bg-opacity: 0.1;
  background-color: rgba(107, 114, 128, var(--tw-bg-opacity));
}
.div-all-employee::-webkit-scrollbar {
  width: 4px;
  height: 10px;
}
.div-all-employee::-webkit-scrollbar-track {
  background: rgb(239, 239, 239);
  border-radius: 2px;
}
.div-all-employee::-webkit-scrollbar-thumb {
  background: #bfbfbf;
  border-radius: 10px;
}
.div-all-employee::-webkit-scrollbar-thumb:hover {
  background: #333;
}
.div-all-employee::-webkit-scrollbar-corner {
  background: #179a16;
}
</style>
